package com.tsd.jxc.sale.service.impl;

import com.tsd.common.vo.BatchDeleteLogicVo;
import com.tsd.core.thread.ThreadPoolTaskUtil;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.jxc.goods.entity.JxcGoodsPriceExt;
import com.tsd.jxc.goods.service.JxcGoodsPriceService;
import com.tsd.jxc.sale.dao.JxcSaleOrderDetailMapper;
import com.tsd.jxc.sale.dao.JxcSaleOrderMapper;
import com.tsd.jxc.sale.dao.JxcSaleReturnBillDetailMapper;
import com.tsd.jxc.sale.dao.JxcSaleReturnBillMapper;
import com.tsd.jxc.sale.entity.JxcSaleOrderDetailExt;
import com.tsd.jxc.sale.entity.JxcSaleReturnBillDetail;
import com.tsd.jxc.sale.entity.JxcSaleReturnBillDetailExt;
import com.tsd.jxc.sale.entity.JxcSaleReturnBillExt;
import com.tsd.jxc.sale.service.JxcSaleReturnBillDetailService;
import com.tsd.jxc.stock.StockConstants;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.entity.SysUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 描述：JxcSaleReturnBillDetail 服务实现层
 *
 * @author Hillpool
 * @date 2022/07/29 15:04:27
 */
@Service
public class JxcSaleReturnBillDetailServiceImpl extends BaseServiceImpl implements JxcSaleReturnBillDetailService {

    @Resource
    private JxcSaleReturnBillDetailMapper jxcSaleReturnBillDetailMapper;
    @Resource
    private JxcSaleReturnBillMapper jxcSaleReturnBillMapper;
    @Resource
    private JxcSaleOrderDetailMapper jxcSaleOrderDetailMapper;
    @Resource
    private JxcSaleOrderMapper jxcSaleOrderMapper;
    @Resource
    private JxcGoodsPriceService jxcGoodsPriceService;

    @Override
    public JxcSaleReturnBillDetail getJxcSaleReturnBillDetailById(Long id) throws Exception {
        return jxcSaleReturnBillDetailMapper.selectByPrimaryKey(id);
    }

    @Override
    public JxcSaleReturnBillDetailExt queryBySid(String sid) throws Exception {
        return jxcSaleReturnBillDetailMapper.selectBySid(sid);
    }

    @Override
    public List<JxcSaleReturnBillDetailExt> queryValidByReturnList(List<String> return_list) {
        List<JxcSaleReturnBillDetailExt> detailExtList = ThreadPoolTaskUtil.queryInList4Split(return_list, list -> {
            JxcSaleReturnBillDetailExt params = new JxcSaleReturnBillDetailExt();
            params.setDr(0);
            params.setReturn_list(list);
            return jxcSaleReturnBillDetailMapper.selectByEntity(params);
        });
        if (!HlpUtils.isEmptyList(detailExtList)) {
            List<String> goodsList = ListUtil.map(detailExtList, JxcSaleReturnBillDetailExt::getGoods_sid);
            List<JxcGoodsPriceExt> priceExtList = jxcGoodsPriceService.queryByGoodsList(goodsList);
            for (JxcSaleReturnBillDetailExt detailExt : detailExtList) {
                List<JxcGoodsPriceExt> filters = ListUtil.filter(priceExtList, t -> t.getGoods_sid().equals(detailExt.getGoods_sid()));
                detailExt.setPrice_list(filters);
                detailExt.calcGoodsPrice();
            }
        }
        return detailExtList;
    }

    @Override
    public void deleteJxcSaleReturnBillDetails(List<String> list, SysUser opUser) throws Exception {
        for (String sid : list) {
            JxcSaleReturnBillDetail old = jxcSaleReturnBillDetailMapper.selectBySid(sid);
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_DELETE);
            jxcSaleReturnBillDetailMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public void saveJxcSaleReturnBillDetail(JxcSaleReturnBillDetail record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            super.autoInjectBaseData(record, opUser, this.TYPE_CREATE);
            jxcSaleReturnBillDetailMapper.insertSelective(record);
        } else {
            super.autoInjectBaseData(record, opUser, this.TYPE_UPDATE);
            jxcSaleReturnBillDetailMapper.updateByPrimaryKeySelective(record);
        }
    }

    @Override
    public void saveJxcSaleReturnBillDetail(JxcSaleReturnBillExt record, SysUser opUser) throws Exception {
        List<JxcSaleReturnBillDetailExt> detailExtList = record.getDetail_list();
        super.checkEmptyList(detailExtList, "退货明细不能为空");

        List<Long> existIdList = ListUtil.filterMap(detailExtList, t -> !HlpUtils.isEmpty(t.getId()), JxcSaleReturnBillDetailExt::getId);

        JxcSaleReturnBillDetailExt params = new JxcSaleReturnBillDetailExt();
        params.setDr(0);
        params.setReturn_sid(record.getSid());
        List<JxcSaleReturnBillDetailExt> oldList = jxcSaleReturnBillDetailMapper.selectByEntity(params);

        //删除不存在的退货明细
        List<JxcSaleReturnBillDetailExt> delList = ListUtil.filter(oldList, t -> !existIdList.contains(t.getId()));
        if (!HlpUtils.isEmptyList(delList)) {
            List<Long> delIds = ListUtil.map(delList, JxcSaleReturnBillDetailExt::getId);
            BatchDeleteLogicVo logicVo = new BatchDeleteLogicVo(opUser);
            logicVo.setIdList(delIds);
            jxcSaleReturnBillDetailMapper.deleteLogicByIdList(logicVo);
        }

        List<JxcSaleReturnBillDetailExt> insertList = new ArrayList<>();
        List<JxcSaleReturnBillDetailExt> updateList = new ArrayList<>();
        double totalQty = 0D, totalAmount = 0D;
        for (JxcSaleReturnBillDetailExt detailExt : detailExtList) {
            if (HlpUtils.isEmpty(detailExt.getIn_bill())) {
                detailExt.setIn_bill(StockConstants.DETAIL_IN_OUT_BILL_NONE);
            }
            super.checkEmpty(detailExt.getQty(), "第" + detailExt.getSn() + "项明细数量不能为空");
            super.checkEmpty(detailExt.getPrice(), "第" + detailExt.getSn() + "项明细单价不能为空");
            detailExt.setReturn_sid(record.getSid());
            if (HlpUtils.isEmpty(detailExt.getAmount())) {
                double amount = DoubleUtil.mul(detailExt.getQty(), detailExt.getPrice());
                detailExt.setAmount(BigDecimal.valueOf(amount));
            }
            totalQty = DoubleUtil.add(totalQty, detailExt.getQty());
            totalAmount = DoubleUtil.add(totalAmount, detailExt.getAmount());
            if (HlpUtils.isEmpty(detailExt.getId())) {
                super.autoInjectBaseData(detailExt, opUser, this.TYPE_CREATE);
                insertList.add(detailExt);
            } else {
                super.autoInjectBaseData(detailExt, opUser, this.TYPE_UPDATE);
                updateList.add(detailExt);
            }
            if (insertList.size() == 100) {
                jxcSaleReturnBillDetailMapper.insertList(insertList);
                insertList.clear();
            }
            if (updateList.size() == 100) {
                jxcSaleReturnBillDetailMapper.updateList(updateList);
                updateList.clear();
            }
        }
        if (!HlpUtils.isEmptyList(insertList)) {
            jxcSaleReturnBillDetailMapper.insertList(insertList);
        }
        if (!HlpUtils.isEmptyList(updateList)) {
            jxcSaleReturnBillDetailMapper.updateList(updateList);
        }

        record.setQty(BigDecimal.valueOf(totalQty));
        record.setAmount(BigDecimal.valueOf(totalAmount));
        if (!HlpUtils.isEmpty(record.getFree_shipping()) && record.getFree_shipping() == 1) {
            record.setTotal_amount(record.getAmount());
        } else {
            double value = DoubleUtil.add(totalAmount, record.getReal_freight());
            record.setTotal_amount(BigDecimal.valueOf(value));
        }

        double shouldReturnAmount = record.getTotal_amount().doubleValue();
        if (!HlpUtils.isEmpty(record.getIgnore_amount())) {
            shouldReturnAmount = DoubleUtil.sub(shouldReturnAmount, record.getIgnore_amount());
        }
        record.setShould_return_amount(BigDecimal.valueOf(shouldReturnAmount));

        double unReturnAmount = record.getShould_return_amount().doubleValue();
        if (!HlpUtils.isEmpty(record.getReturn_amount())) {
            unReturnAmount = DoubleUtil.sub(unReturnAmount, record.getReturn_amount());
        }
        if (unReturnAmount < 0) {
            throw new HlpException("已退金额不能大于应退金额");
        }
        record.setUn_return_amount(BigDecimal.valueOf(unReturnAmount));
        jxcSaleReturnBillMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public List<JxcSaleReturnBillDetailExt> findJxcSaleReturnBillDetails(Map<String, Object> params, PageBean page) throws Exception {
        return jxcSaleReturnBillDetailMapper.selectByPage(params, page);
    }

    @Override
    public List<JxcSaleReturnBillDetailExt> findJxcSaleReturnBillDetails(Map<String, Object> params) throws Exception {
        return jxcSaleReturnBillDetailMapper.selectByParams(params);
    }

    @Override
    public void updateReturn2SaleOrder(List<String> return_bill_list) throws Exception {
        List<String> sidList = jxcSaleReturnBillDetailMapper.selectSaleDetailSidByReturnSidList(return_bill_list);
        jxcSaleOrderDetailMapper.updateReturnInfo(sidList);
        jxcSaleOrderMapper.updateReturnInfo(return_bill_list);
    }
}
